#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import os
import sys
import time
import getopt
import subprocess


usage = """使用方式：
    python coredump_monitor.py -p corepath -u username -f function -e

"""


class Cfg(object):
    path = None
    user = None
    edata = False
    function = None

    @staticmethod
    def init():
        argv = sys.argv[1:]
        short_options = 'p:u:ef:'
        long_options = ['corepath=', 'user=', 'edata', 'function=']
        opts, args = getopt.getopt(argv, short_options, long_options)
        if len(args) > 1:
            print('unknown param ' + args[0])
            exit(1)
        for opt, arg in opts:
            if opt in ['-p', '--corepath']:
                Cfg.path = arg
            elif opt in ['-u', '--user']:
                Cfg.user = arg
            elif opt in ['-e', '--edata']:
                Cfg.edata = True
            elif opt in ['-f', '--function']:
                Cfg.function = arg
            else:
                assert False


def get_my_coredumps():
    cmd = f'ls -ltr {Cfg.path} | grep {Cfg.user}'
    status, output = subprocess.getstatusoutput(cmd)

    return [line.split()[-1] for line in output.splitlines()]


def monitor_run():
    coremap = {}
    while True:
        cores = get_my_coredumps()
        for core in cores:
            if core in coremap:
                print(core, coremap[core])
                continue

            # cmd = f"cd {Cfg.path} && lz4 -d {core} > carrotom.temp.core"
            # time.sleep(30, '等待core解压')
            # cmd = f"source ~/cluster.source && cd {Cfg.path} && gdb gaussdb carrotom.temp.core -ex 'bt' -ex 'q'"

            cmd = f"source ~/cluster.source && cd {Cfg.path} && gdb gaussdb {core} -ex 'bt' -ex 'q'"
            status, output = subprocess.getstatusoutput(cmd)

            # 看看函数堆栈是不是自己想要的
            if Cfg.function is not None and output.find(Cfg.function) <= 0:
                coremap[core] = ' - '
                continue

            if Cfg.edata is None:
                coremap[core] = Cfg.function
                continue

            stacks = output.splitlines()
            fool = 0
            for line in stacks:
                if line.find('in errfinish ') > 0:
                    fool = line[1:3]
                    break
            if fool == 0:
                coremap[core] = f'{Cfg.function}  no errfinish'
                continue
            cmd = f"source ~/cluster.source && cd {Cfg.path} && gdb gaussdb {core} -ex 'f {fool}' -ex 'p edata->message' -ex 'q'"
            status, output = subprocess.getstatusoutput(cmd)
            coredetial = '\t' + ' '.join(output.splitlines()[-1].split()[3:])
            coremap[core] = f'{Cfg.function} {coredetial}'

        time.sleep(600)


if __name__ == '__main__':
    Cfg.init()
    monitor_run()
